import tkinter as tk
from tkinter import filedialog, messagebox
from pathlib import Path
import shutil
import threading


class FileOrganizerApp:
    """文件分类整理工具"""
    
    # 文件类型分类映射
    FILE_CATEGORIES = {
        '图片': ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.webp', '.ico', '.tiff'],
        '文档': ['.pdf', '.doc', '.docx', '.txt', '.rtf', '.odt', '.pages'],
        '表格': ['.xls', '.xlsx', '.csv', '.numbers'],
        '演示': ['.ppt', '.pptx', '.key'],
        '压缩包': ['.zip', '.rar', '.7z', '.tar', '.gz', '.bz2'],
        '视频': ['.mp4', '.avi', '.mkv', '.mov', '.wmv', '.flv', '.webm'],
        '音频': ['.mp3', '.wav', '.flac', '.aac', '.ogg', '.m4a', '.wma'],
        '代码': ['.py', '.js', '.html', '.css', '.java', '.cpp', '.c', '.go', '.rs'],
        '可执行文件': ['.exe', '.app', '.dmg', '.pkg', '.deb', '.rpm'],
        '其他': []  # 未分类的文件
    }
    
    def __init__(self, root):
        self.root = root
        self.root.title("文件分类整理工具")
        self.root.geometry("650x500")
        self.root.resizable(False, False)
        
        # 居中显示窗口
        self.center_window()
        
        # 选中的文件夹路径
        self.folder_path = None
        
        # 创建UI
        self.create_widgets()
    
    def center_window(self):
        """使窗口居中显示"""
        self.root.update_idletasks()
        width = self.root.winfo_width()
        height = self.root.winfo_height()
        x = (self.root.winfo_screenwidth() // 2) - (width // 2)
        y = (self.root.winfo_screenheight() // 2) - (height // 2)
        self.root.geometry(f'{width}x{height}+{x}+{y}')
    
    def create_widgets(self):
        """创建界面组件"""
        # 文件夹选择框架
        folder_frame = tk.Frame(self.root, pady=10)
        folder_frame.pack(fill=tk.X, padx=20)
        
        self.folder_label = tk.Label(
            folder_frame,
            text="未选择文件夹",
            bg="#f0f0f0",
            anchor="w",
            padx=10,
            pady=10,
            relief=tk.SUNKEN
        )
        self.folder_label.pack(side=tk.LEFT, fill=tk.X, expand=True)
        
        select_btn = tk.Button(
            folder_frame,
            text="选择文件夹",
            command=self.select_folder,
            padx=15,
            pady=10,
            bg="#4CAF50",
            fg="black",
            font=("Arial", 10, "bold"),
            cursor="hand2"
        )
        select_btn.pack(side=tk.RIGHT, padx=(10, 0))
        
        # 说明文字
        info_frame = tk.Frame(self.root, pady=10)
        info_frame.pack(fill=tk.X, padx=20)
        
        info_text = tk.Label(
            info_frame,
            text="将按文件类型自动分类到以下文件夹：",
            font=("Arial", 10),
            anchor="w",
            fg="#333"
        )
        info_text.pack(anchor="w")
        
        # 分类列表框架
        categories_frame = tk.Frame(self.root, pady=5)
        categories_frame.pack(fill=tk.BOTH, expand=True, padx=20)
        
        # 使用Text widget显示分类信息（只读）
        self.categories_text = tk.Text(
            categories_frame,
            height=12,
            font=("Arial", 9),
            bg="#f9f9f9",
            relief=tk.SUNKEN,
            padx=10,
            pady=10
        )
        self.categories_text.pack(fill=tk.BOTH, expand=True)
        
        # 填充分类信息
        self.display_categories()
        self.categories_text.config(state=tk.DISABLED)
        
        # 文件统计标签
        self.stats_label = tk.Label(
            self.root,
            text="",
            font=("Arial", 9),
            fg="#666"
        )
        self.stats_label.pack(pady=(10, 5))
        
        # 状态标签
        self.status_label = tk.Label(
            self.root,
            text="请选择需要整理的文件夹",
            font=("Arial", 9),
            fg="#666"
        )
        self.status_label.pack(pady=(0, 10))
        
        # 按钮框架
        button_frame = tk.Frame(self.root)
        button_frame.pack(pady=(0, 20))
        
        # 预览按钮
        self.preview_btn = tk.Button(
            button_frame,
            text="预览分类",
            command=self.preview_organization,
            padx=20,
            pady=12,
            bg="#FF9800",
            fg="black",
            font=("Arial", 10, "bold"),
            cursor="hand2",
            state=tk.DISABLED
        )
        self.preview_btn.pack(side=tk.LEFT, padx=5)
        
        # 整理按钮
        self.organize_btn = tk.Button(
            button_frame,
            text="开始整理",
            command=self.start_organize,
            padx=20,
            pady=12,
            bg="#1976D2",
            fg="black",
            font=("Arial", 10, "bold"),
            cursor="hand2",
            state=tk.DISABLED
        )
        self.organize_btn.pack(side=tk.LEFT, padx=5)
    
    def display_categories(self):
        """显示分类信息"""
        self.categories_text.config(state=tk.NORMAL)
        self.categories_text.delete(1.0, tk.END)
        
        for category, extensions in self.FILE_CATEGORIES.items():
            if extensions:  # 不显示"其他"类别
                exts = ', '.join(extensions[:8])  # 只显示前8个扩展名
                if len(extensions) > 8:
                    exts += f" ... (共{len(extensions)}种)"
                self.categories_text.insert(tk.END, f"📁 {category}：{exts}\n")
        
        self.categories_text.insert(tk.END, "\n📁 其他：未分类的文件类型")
        self.categories_text.config(state=tk.DISABLED)
    
    def select_folder(self):
        """选择文件夹"""
        folder = filedialog.askdirectory(title="选择需要整理的文件夹")
        if folder:
            self.folder_path = folder
            self.folder_label.config(text=folder)
            self.scan_files()
    
    def scan_files(self):
        """扫描文件夹中的文件"""
        if not self.folder_path:
            return
        
        folder = Path(self.folder_path)
        files = [f for f in folder.iterdir() if f.is_file()]
        
        if files:
            self.stats_label.config(
                text=f"检测到 {len(files)} 个文件待整理",
                fg="#4CAF50"
            )
            self.status_label.config(
                text="可以开始预览或整理文件",
                fg="#666"
            )
            self.preview_btn.config(state=tk.NORMAL)
            self.organize_btn.config(state=tk.NORMAL)
        else:
            self.stats_label.config(
                text="文件夹中没有文件",
                fg="#F44336"
            )
            self.status_label.config(
                text="请选择包含文件的文件夹",
                fg="#F44336"
            )
            self.preview_btn.config(state=tk.DISABLED)
            self.organize_btn.config(state=tk.DISABLED)
    
    def get_category(self, file_path):
        """根据文件扩展名获取分类"""
        ext = file_path.suffix.lower()
        for category, extensions in self.FILE_CATEGORIES.items():
            if ext in extensions:
                return category
        return '其他'
    
    def preview_organization(self):
        """预览文件分类结果"""
        if not self.folder_path:
            return
        
        folder = Path(self.folder_path)
        files = [f for f in folder.iterdir() if f.is_file()]
        
        # 统计各分类的文件数量
        category_stats = {}
        for file in files:
            category = self.get_category(file)
            category_stats[category] = category_stats.get(category, 0) + 1
        
        # 生成预览信息
        preview_text = "文件分类预览：\n\n"
        for category, count in sorted(category_stats.items()):
            preview_text += f"📁 {category}：{count} 个文件\n"
        
        preview_text += f"\n总计：{len(files)} 个文件"
        
        messagebox.showinfo("分类预览", preview_text)
    
    def start_organize(self):
        """开始整理（在新线程中执行）"""
        result = messagebox.askyesno(
            "确认整理",
            "确定要开始整理文件吗？\n\n"
            "文件将被移动到对应的分类文件夹中。\n"
            "建议先备份重要文件！"
        )
        
        if result:
            # 禁用按钮，防止重复点击
            self.preview_btn.config(state=tk.DISABLED)
            self.organize_btn.config(state=tk.DISABLED)
            
            # 在新线程中执行整理操作
            thread = threading.Thread(target=self.organize_files, daemon=True)
            thread.start()
    
    def organize_files(self):
        """整理文件"""
        try:
            self.status_label.config(text="正在整理文件...", fg="#2196F3")
            
            if not self.folder_path:
                raise Exception("未选择文件夹")
            
            folder = Path(self.folder_path)
            files = [f for f in folder.iterdir() if f.is_file()]
            
            if not files:
                raise Exception("文件夹中没有文件")
            
            # 统计信息
            moved_count = 0
            category_counts = {}
            
            # 整理每个文件
            for file in files:
                try:
                    category = self.get_category(file)
                    
                    # 创建分类文件夹
                    category_folder = folder / category
                    category_folder.mkdir(exist_ok=True)
                    
                    # 移动文件
                    dest_path = category_folder / file.name
                    
                    # 如果目标文件已存在，添加序号
                    if dest_path.exists():
                        base_name = file.stem
                        extension = file.suffix
                        counter = 1
                        while dest_path.exists():
                            dest_path = category_folder / f"{base_name}_{counter}{extension}"
                            counter += 1
                    
                    shutil.move(str(file), str(dest_path))
                    moved_count += 1
                    category_counts[category] = category_counts.get(category, 0) + 1
                    
                except Exception as e:
                    print(f"移动文件 {file.name} 时出错: {str(e)}")
                    continue
            
            # 更新状态
            self.root.after(0, lambda: self.organize_complete(moved_count, category_counts))
            
        except Exception as e:
            self.root.after(0, lambda: self.organize_error(str(e)))
    
    def organize_complete(self, moved_count, category_counts):
        """整理完成"""
        self.status_label.config(
            text=f"整理完成！共移动 {moved_count} 个文件",
            fg="#4CAF50"
        )
        self.preview_btn.config(state=tk.NORMAL)
        self.organize_btn.config(state=tk.NORMAL)
        
        # 生成详细统计信息
        stats_text = f"文件整理完成！\n\n共处理 {moved_count} 个文件：\n\n"
        for category, count in sorted(category_counts.items()):
            stats_text += f"📁 {category}：{count} 个文件\n"
        
        result = messagebox.showinfo("整理完成", stats_text + "\n是否打开文件夹？")
        
        if result == 'ok':
            import os
            os.system(f'open "{self.folder_path}"')
        
        # 重新扫描
        self.scan_files()
    
    def organize_error(self, error_msg):
        """整理出错"""
        self.status_label.config(
            text="整理失败",
            fg="#F44336"
        )
        self.preview_btn.config(state=tk.NORMAL)
        self.organize_btn.config(state=tk.NORMAL)
        
        messagebox.showerror(
            "整理失败",
            f"整理文件时出错：\n{error_msg}"
        )


def main():
    """主函数"""
    root = tk.Tk()
    app = FileOrganizerApp(root)
    root.mainloop()


if __name__ == "__main__":
    main()
